package com.yupi.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mdd.model.entity.UserInterfaceInfo;
import com.yupi.project.common.ErrorCode;
import com.yupi.project.exception.ThrowUtils;
import com.yupi.project.exception.BusinessException;
import com.yupi.project.service.UserInterfaceInfoService;
import com.yupi.project.mapper.UserInterfaceInfoMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* @author 21958
* @description 针对表【user_interface_info(用户调用接口关系)】的数据库操作Service实现
* @createDate 2023-07-18 17:22:18
*/
@Service
public class UserInterfaceInfoServiceImpl extends ServiceImpl<UserInterfaceInfoMapper, UserInterfaceInfo>
    implements UserInterfaceInfoService{

    @Override
    public void validUserInterfaceInfo(UserInterfaceInfo userInterfaceInfo, boolean add) {


        if (userInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Long interfaceInfoId = userInterfaceInfo.getInterfaceInfoId();
        Integer totalNum = userInterfaceInfo.getTotalNum();
        Integer leftNum = userInterfaceInfo.getLeftNum();
        // 创建时，所有参数必须非空
        if (add) {
            if (interfaceInfoId == null || totalNum == null || leftNum == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
            }
            if (interfaceInfoId <= 0 || totalNum < 0 || leftNum < 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
        }
        if (leftNum < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"剩余次数不能小于0");
        }
    }

    private static final int DEFAULT_INVOKE_NUM = 1000;

    @Override
    public boolean invokeCount(long userId, long interfaceId) {
        //参数校验
        if (userId <= 0 || interfaceId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 校验是否有用户调用接口的记录
        LambdaQueryWrapper<UserInterfaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInterfaceInfo::getUserId,userId).eq(UserInterfaceInfo::getInterfaceInfoId,interfaceId);
        UserInterfaceInfo userInterfaceInfo = getOne(queryWrapper);
        if (userInterfaceInfo == null) {
            // 没有记录，则创建用户调用接口记录，分配调用次数
            UserInterfaceInfo nUserInterfaceInfo = new UserInterfaceInfo();
            nUserInterfaceInfo.setUserId(userId);
            nUserInterfaceInfo.setInterfaceInfoId(interfaceId);
            //分配一千次调用
            nUserInterfaceInfo.setLeftNum(DEFAULT_INVOKE_NUM);
            boolean res = save(nUserInterfaceInfo);
            ThrowUtils.throwIf(!res,ErrorCode.OPERATION_ERROR);
        }
        //有，调用次数+1
        //加锁，防止并发下的线程安全问题
        synchronized ((userId+"").intern()){
            LambdaUpdateWrapper<UserInterfaceInfo> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserInterfaceInfo::getUserId,userId)
                    .eq(UserInterfaceInfo::getInterfaceInfoId,interfaceId)
                    .ge(UserInterfaceInfo::getTotalNum,0)
                    .gt(UserInterfaceInfo::getLeftNum,0).setSql("leftNum=leftNum-1,totalNum=totalNum+1");
            boolean res = update(updateWrapper);
            ThrowUtils.throwIf(!res,ErrorCode.OPERATION_ERROR,"信息更新失败!");
            return true;
        }
    }
}




